package in.co.codedoc.cg.velocity;

import in.co.codedoc.cg.BeanUtil;
import in.co.codedoc.cg.annotations.CacheKey;
import in.co.codedoc.cg.annotations.IsCached;
import in.co.codedoc.cg.annotations.IsMappedToTable;

import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.parser.node.Node;

import com.sun.mirror.declaration.TypeDeclaration;

public class ClassAccessBlockDirective 
	extends CGBlockDirective
{
	public ClassAccessBlockDirective()
	{
		super("current class type definition object");
	}
	
	@Override
	public String getName()
	{
		return "ClassAccessBlock";
	}

	@Override
	public boolean render(InternalContextAdapter context, Writer writer,
			Node node) throws IOException, ResourceNotFoundException,
			ParseErrorException, MethodInvocationException
	{
		TypeDeclaration currentClassTD = (TypeDeclaration)node.jjtGetChild(0).value(context);
		
		try
		{
			IsMappedToTable imtt = currentClassTD.getAnnotation(IsMappedToTable.class);
			context.put("isMappedToTable",imtt != null);
			if(imtt != null)
			{
				context.put("mappedTable",imtt.value());
			}
			
			IsCached isCached = currentClassTD.getAnnotation(IsCached.class);
			context.put("isCached",isCached != null);
			if(isCached != null)
			{
				ArrayList<ArrayList<String>> keys = new ArrayList<ArrayList<String>>();
				if(isCached.value() == null || isCached.value().length == 0)
				{
					throw new RuntimeException
					(
						"IsCached must define at least one CacheKey:" + 
						isCached.toString() + " does not do so."
					);
				}
				for(CacheKey ck:isCached.value())
				{
					ArrayList<String> kcs = new ArrayList<String>();
					if(ck.value() == null || ck.value().isEmpty())
					{
						throw new RuntimeException
						(
							"CacheKey must indicate a comma separated list of properties:" + 
							isCached.toString() + " does not do so."
						);
					}
					for(String kc:ck.value().split(","))
					{
						kcs.add(BeanUtil.GetUCased(kc));
					}
					keys.add(kcs);
				}
				
				context.put("cacheKeys", keys);
			}
		}
		catch(Throwable th)
		{
			
		}
		
		try
		{
			node.jjtGetChild(node.jjtGetNumChildren()-1).render(context, writer);
		}
		finally
		{
			context.remove("isMappedToTable");
			context.remove("mappedTable");
			context.remove("isCached");
			context.remove("cacheKeys");
		}
		
		return true;
	}
}
